<?php

/**
 *  经销商商品
 */

namespace app\api\service;

use app\api\model\Product;
use app\api\model\Inventory;
use app\api\model\ProductCurrencyLink;
use app\api\model\ProductPrice;
use app\api\model\Warehouse;
use app\common\Calculate;
use app\facade\Basic;
use think\facade\Lang;
use Exception;
use app\admin\model\Images;
use app\admin\model\TransactionCurrency;
use app\api\service\Product as ProductService;
use think\facade\Db;

class DistributorProduct
{


    /**
     *  通过货币获取矿机ID
     */
    public function getCurrencyByids($minableCoin)
    {
        $result = ProductCurrencyLink::field('productid')->where('currencyid', 'in', $minableCoin)->group('productid')->select();
        if (!$result) {
            return null;
        }
        $result = $result->toArray();
        $ids = [];
        foreach ($result as $value) {
            $ids[] = $value['productid'];
        }
        return $ids;
    }

    /**
     *
     */
    public function arrayFilterFieldValue($data, $field, $value)
    {
        foreach ($data as  $row) {
            if ($row[$field] == $value) {
                return $row;
            }
        }
    }

    /**
     *  供应商商品列表
     */
    public function list($param)
    {
        // 获取查询条件
        [$product_ids, $where_wid, $where_is_futures] = $this->getQueryConditions($param);
        if (empty($product_ids)) {
            return Basic::data(0, 'common.success', ['list' => []]);
        }

        // 获取库存数据
        $inventory = $this->getInventoryData($product_ids, $where_wid, $where_is_futures);
        if (empty($inventory)) {
            return Basic::data(0, 'common.success', ['list' => []]);
        }

        // 处理库存数据
        $inventory_data = $this->processInventoryData($inventory, $param);
        if (empty($inventory_data)) {
            return Basic::data(0, 'common.success', ['list' => []]);
        }

        // 批量查询相关数据
        [$products, $warehouses, $prices] = $this->getRelatedData($inventory_data);

        // 格式化数据
        $target = $param['lang'] ?? 'en';
        [$data, $tanslateParam] = $this->formatData($inventory_data, $products, $warehouses, $prices, $target);

        // 排序
        $data = $this->sortData($data, $param['sort'] ?? null);

        // 翻译处理
        $data = $this->translateData($data, $tanslateParam, $target);

        if (isset($param['keywords']) && $param['keywords']) {
            $keywords = $param['keywords'];
            $data = array_filter($data, function ($item) use ($keywords) {
                return stripos($item['name'], $keywords) !== false;
            });
            $data = array_values($data);
        }

        if (2 == $param['action']) { // 导出数据 获取矿机收益
            $data = $this->getMinerProfit($data, $target);
        }

        return Basic::data(0, 'common.success', ['list' => $data]);
    }

    /**
     * 获取查询条件（产品ID和仓库条件）
     */
    private function getQueryConditions($param)
    {
        // 构建产品查询条件
        $product_where = [
            'status' => 1,
            'is_del' => 0
        ];

        // 品牌筛选
        if (!empty($param['brand']) && $param['brand'][0] !== 'all') {
            $product_where[] = ['brand', 'in', $param['brand']];
        }

        // 是否二手机
        if (!is_null($param['condition']) && !empty($param['condition'])) {
            $product_where[] = ['condition', '=', $param['condition']];
        }

        // 货币筛选 - 使用原生SQL条件
        $algorithm_condition = null;
        if (!empty($param['minable_coin']) && $param['minable_coin'][0] !== 'all') {
            $result = Db::name('product_currency')->where('id', 'in', $param['minable_coin'])->column('algorithm');
            if ($result) {
                $algorithm_condition = 'FIND_IN_SET("' . implode('", algorithm) > 0 OR FIND_IN_SET("', $result) . '", algorithm) > 0';
            }
        }

        if (isset($param['product_type']) && $param['product_type'] > 0) {
            $product_where[] = ['type', '=', $param['product_type']];
        }

        // 获取产品ID
        $productQuery = Product::where($product_where);
        if ($algorithm_condition) {
            $productQuery->whereRaw($algorithm_condition);
        }
        $product_ids = $productQuery->column('id');

        // 构建仓库查询条件
        $where_wid = null;
        if (!empty($param['warehouse']) && $param['warehouse'][0] !== 'all') {
            $where_wid = array_map(function ($wid) {
                return "FIND_IN_SET('$wid', wid) > 0";
            }, $param['warehouse']);
        }

        $where_is_futures = null;
        if (isset($param['is_futures']) && $param['is_futures'] > -1) {
            $where_is_futures = $param['is_futures'];
        }

        return [$product_ids, $where_wid, $where_is_futures];
    }

    /**
     * 获取库存数据
     */
    private function getInventoryData($product_ids, $where_wid, $where_is_futures)
    {
        $inventory_where = [
            ['productid', 'in', $product_ids],
            ['is_sale', '=', 1],
            ['is_del', '=', 0]
        ];

        $disabled_warehouse_ids = Warehouse::where('status', 0)->column('id');

        $inventoryQuery = Inventory::field(
            'MAX(id) as id,
            SUM(available_qty) as available_qty,
            SUM(lock_qty) as lock_qty,
            productid,
            wid,
            is_futures,
            real_arrival_date as arrival_date,
            allow_zero_stock_sale'
        )
            ->group('productid,wid,is_futures,real_arrival_date,allow_zero_stock_sale')
            ->where($inventory_where)
            ->where(function ($query) {
                $query->where('available_qty', '>', 'lock_qty')
                    ->whereOr('allow_zero_stock_sale', '=', 1);
            })
            ->order('productid desc');

        if ($where_wid) {
            $inventoryQuery->whereRaw(implode(' OR ', $where_wid));
        }

        if (isset($where_is_futures) && $where_is_futures > -1) {
            if ($where_is_futures == 0) {
                $inventoryQuery->where('is_futures', '=', 0);
            } else {
                $inventoryQuery->where('is_futures', 'in', [1, 2]);
            }
        }

        // 排除禁用仓库 - 处理逗号分隔的wid字符串
        if (!empty($disabled_warehouse_ids)) {
            $disabled_conditions = [];
            foreach ($disabled_warehouse_ids as $disabled_id) {
                $disabled_conditions[] = "FIND_IN_SET('$disabled_id', wid) = 0";
            }
            $inventoryQuery->whereRaw(implode(' AND ', $disabled_conditions));
        }

        return $inventoryQuery->select()->toArray();
    }

    /**
     * 处理库存数据
     */
    private function processInventoryData($inventory, $param)
    {
        $inventory_data = [];
        foreach ($inventory as $inventoryValue) {
            $available_qty = Calculate::pricecalc($inventoryValue['available_qty'], '-', $inventoryValue['lock_qty'], 0);
            if ($available_qty > 0 || $inventoryValue['allow_zero_stock_sale'] == 1) {
                $inventory_item = [
                    'inventory_id' => $inventoryValue['id'],
                    'available_qty' => $available_qty,
                    'productid' => $inventoryValue['productid'],
                    'wid' => $inventoryValue['wid'],
                    'is_futures' => $inventoryValue['is_futures'],
                    'arrival_date' => $inventoryValue['arrival_date'],
                    'allow_zero_stock_sale' => $inventoryValue['allow_zero_stock_sale']
                ];

                // 处理虚拟仓库拆分
                if (strpos($inventory_item['wid'], ',') !== false) {
                    foreach (explode(',', $inventoryValue['wid']) as $wid) {
                        if (empty($param['warehouse']) || $param['warehouse'][0] === 'all' || in_array($wid, $param['warehouse'])) {
                            $inventory_item['wid'] = $wid;
                            $inventory_data[] = $inventory_item;
                        }
                    }
                } else {
                    $inventory_data[] = $inventory_item;
                }
            }
        }
        return $inventory_data;
    }

    /**
     * 批量查询相关数据
     */
    private function getRelatedData($inventory_data)
    {
        $product_ids = array_unique(array_column($inventory_data, 'productid'));
        $warehouse_ids = array_unique(array_column($inventory_data, 'wid'));
        $inventory_ids = array_unique(array_column($inventory_data, 'inventory_id'));
        // 获取产品数据
        $products_result = Product::with([
            'brand' => function ($query) {
                return $query->field('id,name,image');
            },
            'category' => function ($query) {
                return $query->field('id,name');
            }
        ])->alias('a')
            ->leftJoin('db_product_relation b', 'a.id = b.pid')
            ->leftJoin('db_product_merge c', 'b.pm_id = c.id')
            ->whereIn('a.id', $product_ids)
            ->where('a.is_del', 0)
            ->field('a.id,a.cname,a.brand,a.condition,a.expiration_date,a.category,a.hashrate,a.computing_unit,a.power,a.main_photo,a.photo,a.describe,a.estimated_ship_date,a.weight,a.type,c.producturlname')
            ->select()
            ->toArray();

        foreach ($products_result as &$product_photo) {
            if (empty($product_photo['main_photo']) && !empty($product_photo['photo'])) {
                $product_photo['main_photo'] = explode(',', $product_photo['photo'])[0];
            }
        }

        $photoidsArr =  array_column($products_result, 'main_photo', 'id');
        $imageModel = new Images();
        $photoList = $imageModel->getImagesByIds($photoidsArr);

        // 将数组转换为以ID为下标的结构
        $photoList = array_column($photoList, null, 'id');

        // 转换为关联数组
        $products = [];
        foreach ($products_result as $product) {
            if (isset($photoList[$product['main_photo']])) {
                $product['main_photo'] = $photoList[$product['main_photo']]['url'];
            }
            $products[$product['id']] = $product;
        }
        // 获取仓库数据
        $warehouses_result = Warehouse::whereIn('id', $warehouse_ids)
            ->field('id,show_name as name')
            ->select()
            ->toArray();

        $warehouses = [];
        foreach ($warehouses_result as $warehouse) {
            $warehouses[$warehouse['id']] = $warehouse;
        }

        // 获取价格数据
        $prices_result = ProductPrice::with([
            'discounts' => function ($query) {
                return $query->field('id,num,rate,level,price,price_id');
            },

        ])
            ->where([
                ['is_del', '=', '0']
            ])
            ->whereIn('inventory_id', $inventory_ids)
            ->field('id,wid,price,first_leg_logistics_fee,inventory_id,transaction_currency_id,first_leg_logistics_fee')
            ->select()
            ->toArray();

        $transaction_currency_ids = array_column($prices_result, 'transaction_currency_id');
        $transaction_currency_result = TransactionCurrency::whereIn('id', $transaction_currency_ids)->select()->toArray();
        $transaction_currency_result = array_column($transaction_currency_result, 'name', 'id');

        $prices = [];
        foreach ($prices_result as $price) {
            $price['currency'] = $transaction_currency_result[$price['transaction_currency_id']];
            $prices[$price['inventory_id'] . '_' . $price['wid']][(int)$price['transaction_currency_id']] = $price;
        }

        return [$products, $warehouses, $prices];
    }

    /**
     * 格式化数据
     */
    private function formatData($inventory_data, $products, $warehouses, $prices, $target)
    {
        $data = [];
        $tanslateParam = [];
        $product = new Product();
        foreach ($inventory_data as $item) {
            $row = [
                'inventory_id' => $item['inventory_id'],
                'is_futures' => $item['is_futures'],
                'arrival' => $item['arrival_date'] ?: Lang::get('product.inStock'),
                'arrival_date' => $item['arrival_date']
            ];

            // 仓库信息
            if (isset($warehouses[$item['wid']])) {
                $row['warehouse_id'] = $warehouses[$item['wid']]['id'];
                $row['warehouse_name'] = $warehouses[$item['wid']]['name'];

                if ($target != 'en' && $row['warehouse_name']) {
                    $tanslateParam[md5($row['warehouse_name'])] = $row['warehouse_name'];
                }
            }

            // 产品信息
            if (isset($products[$item['productid']])) {
                $productData = $products[$item['productid']];
                $productData['computing_unit'] = $product->getUnitAttr('', $productData);
                $row = array_merge($row, [
                    'product_id' => $productData['id'],
                    'name' => $productData['cname'],
                    'condition' => $productData['condition'],
                    'unit' => $productData['computing_unit'] ?? '',
                    'hashrate' => $productData['hashrate'] . ($productData['computing_unit'] ?? ''),
                    'power' => $productData['power'],
                    'weight' => $productData['weight'],
                    'expiration_date' => $productData['expiration_date'] . Lang::get('product.day'),
                    'thumb' => $productData['main_photo'] ?? '',
                    'category_id' => $productData['category']['id'] ?? '',
                    'category_name' => $productData['category']['name'] ?? '',
                    'brand_id' => $productData['brand']['id'] ?? '',
                    'brand_name' => $productData['brand']['name'] ?? '',
                    'brand_icon' => $productData['brand']['image'] ?? '',
                    'type' => $productData['type'] ?? '',
                    'producturlname' => $productData['producturlname'] ?? ''
                ]);
                if ($target != 'en' && $row['name']) {
                    $tanslateParam[md5($row['name'])] = $row['name'];
                }
            }
            // 价格信息
            $row['price'] = $prices[$item['inventory_id'] . '_' . $item['wid']] ?? '';



            $data[] = $row;
        }

        // 按 type 字段升序排序
        usort($data, function ($a, $b) {
            return ($a['type'] ?? 0) <=> ($b['type'] ?? 0);
        });

        return [$data, $tanslateParam];
    }

    /**
     * 数据排序
     */
    private function sortData($data, $sortType)
    {
        if (empty($sortType)) {
            return $data;
        }

        switch ($sortType) {
            case 1: // 价格从低到高
                usort($data, function ($a, $b) {
                    $priceA = (empty($a['price']) || $a['price'] === null || $a['price'] === '') ? 0 : (float)$a['price'];
                    $priceB = (empty($b['price']) || $b['price'] === null || $b['price'] === '') ? 0 : (float)$b['price'];

                    if ($priceA == 0 && $priceB == 0) return 0;
                    if ($priceA == 0) return -1;
                    if ($priceB == 0) return 1;

                    return $priceA <=> $priceB;
                });
                break;

            case 2: // 价格从高到低
                usort($data, function ($a, $b) {
                    $priceA = (empty($a['price']) || $a['price'] === null || $a['price'] === '') ? 0 : (float)$a['price'];
                    $priceB = (empty($b['price']) || $b['price'] === null || $b['price'] === '') ? 0 : (float)$b['price'];

                    if ($priceA == 0 && $priceB == 0) return 0;
                    if ($priceA == 0) return 1;
                    if ($priceB == 0) return -1;

                    return $priceB <=> $priceA;
                });
                break;
        }

        return $data;
    }

    /**
     * 翻译处理
     */
    private function translateData($data, $tanslateParam, $target)
    {
        if ($target == 'en' || empty($tanslateParam)) {
            return $data;
        }

        try {
            $commonService = new Common();
            $parama = [
                'content' => json_encode($tanslateParam),
                'target_language' => $target
            ];
            $tanslate = $commonService->translate($parama);

            if (isset($tanslate['data'])) {
                foreach ($data as $k => $p) {
                    if (isset($p['warehouse_name']) && isset($tanslate['data'][md5($p['warehouse_name'])])) {
                        $data[$k]['warehouse_name'] = $tanslate['data'][md5($p['warehouse_name'])];
                    }
                    if (isset($p['name']) && isset($tanslate['data'][md5($p['name'])])) {
                        $data[$k]['name'] = $tanslate['data'][md5($p['name'])];
                    }
                }
            }
        } catch (Exception $e) {
            // 翻译失败时保持原文
        }

        return $data;
    }

    /**
     * @describe
     * @author: Bobo
     * @date: 2025-07-09 13:51:16 
     * @param [type] @required
     * @return Renderable
     */
    public function getMinerProfit($data, $target)
    {
        $productService = new ProductService();
        $profit = $productService->profit(['type' => 2], $target);

        if (isset($profit['code']) && $profit['code'] == 0) {
            $profit = $profit['data'];
        }
        $profit = array_column($profit, null, 'id');
        foreach ($data as $k => $v) {
            if (1 == $v['type']) {
                $coins_data = $profit[$v['product_id']]['coins_data'] ?? [];
                // 获取 profit_per_day_usd 最高的值
                $max_profit = 0;
                if (!empty($coins_data)) {
                    $max_profit = max(array_column($coins_data, 'profit_per_day_usd'));
                }

                $data[$k]['profit_per_day_usd'] = $max_profit;
            }
        }
        return $data;
    }
}
